import cv2 as cv
import numpy as np

src = cv.imread(r"./1.jpg")  # 读取图片
ROI = np.zeros(src.shape, np.uint8)  # 创建与原图同尺寸的空numpy数组，用来保存ROI信息

gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)  # 灰度化
ret, binary = cv.threshold(gray,
                           0, 255,
                           cv.THRESH_BINARY_INV | cv.THRESH_TRIANGLE)  # 自适应二值化

contours, hierarchy = cv.findContours(binary,
                                      cv.RETR_EXTERNAL,
                                      cv.CHAIN_APPROX_SIMPLE)  # 查找所有轮廓，每个轮廓信息保存于contours数组中

for cnt in range(len(contours)):  # 基于轮廓数量处理每个轮廓
    # 轮廓逼近，具体原理还需要深入研究
    epsilon = 0.1 * cv.arcLength(contours[cnt], True)
    approx = cv.approxPolyDP(contours[cnt], epsilon, True)  # 保存逼近结果的顶点信息
    # 顶点个数决定轮廓形状
    # 计算轮廓中心位置
    mm = cv.moments(contours[cnt])
    if mm['m00'] != 0:
        cx = int(mm['m10'] / mm['m00'])
        cy = int(mm['m01'] / mm['m00'])
        color = src[cy][cx]
        color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"
        p = cv.arcLength(contours[cnt], True)
        area = cv.contourArea(contours[cnt])

        # 分析几何形状
        corners = len(approx)
        if corners == 4 and area > 1000:
            cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)  # 在ROI空画布上画出轮廓，并填充白色（最后的参数为轮廓线条宽度，如果为负数则直接填充区域）
            imgroi = ROI & src  # ROI和原图进行与运算，筛出原图中的ROI区域
            cv.imshow("ROI", imgroi)
        # if corners == 3 and (color[2] >= 150 or color[0] >= 150) and area > 1000:  # 一系列判定条件是由该项目的特点所调整的
        #     cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)  # 在ROI空画布上画出轮廓，并填充白色（最后的参数为轮廓线条宽度，如果为负数则直接填充区域）
        #     imgroi = ROI & src  # ROI和原图进行与运算，筛出原图中的ROI区域
        #     cv.imshow("ROI", imgroi)
        #     # cv.imwrite(r"./ROI.jpg")
        #
        # if corners >= 10 and (color[2] >= 150 or color[0] >= 150) and area > 1000:
        #     cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)
        #     imgroi = ROI & src
        #     cv.imshow("ROI", imgroi)
        #     # cv.imwrite(r"./ROI.jpg")

            cv.waitKey(0)
            cv.destroyAllWindows()
